﻿using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Linq.Expressions;
using System.Threading;
using System.Windows.Threading;

namespace KS.DataWrapper.DataWrapper
{
    public partial class DataCacheObject<T> : INotifyCollectionChanged, INotifyPropertyChanged
    {
        #region INotifyCollectionChanged
        
        public event NotifyCollectionChangedEventHandler CollectionChanged;
        
        protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
        {
            var dispatcher = Dispatcher.FromThread(Thread.CurrentThread);

            System.Windows.Application.Current.Dispatcher.Invoke(() =>
            {
                var handler = Interlocked.CompareExchange(ref this.CollectionChanged, null, null);

                if (handler != null)
                {
                    try
                    {
                        handler(this, e);
                    }
                    catch (Exception ex)
                    {
                        int a = 0;
                    }
                }
            });

            //if (dispatcher != null)
            //{
            //    dispatcher.Invoke(new Action(() =>
            //    {
                    
            //    }));
            //}
            

            
            //try
            //{
            //    dispatcher.BeginInvoke(new ThreadStart(delegate
            //    {
            //        var handler = Interlocked.CompareExchange(ref this.CollectionChanged, null, null);
                    
            //        if (handler != null)
            //        {
            //            try
            //            {
            //                handler(this, e);
            //            }
            //            catch (Exception ex)
            //            {
            //                int a = 0;
            //            }
            //        }
            //    }));
            //}
            //catch (Exception ex)
            //{
            //    int a = 0;
            //}
        }
        
        #endregion
        
        #region INotifyPropertyChanged
        
        public event PropertyChangedEventHandler PropertyChanged;
        
        protected void OnPropertyChanged<T>(Expression<Func<T>> action)
        {
            var propertyName = GetPropertyName(action);
            this.OnPropertyChanged(propertyName);
        }
        
        private static string GetPropertyName<T>(Expression<Func<T>> action)
        {
            var expression = (MemberExpression)action.Body;
            var propertyName = expression.Member.Name;
            return propertyName;
        }
        
        private void OnPropertyChanged(string propertyName)
        {
            var handler = Interlocked.CompareExchange(ref this.PropertyChanged, null, null);
            
            if (handler != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                try
                {
                    handler(this, e);
                }
                catch (Exception ex)
                {
                    int a = 0;
                }
            }
        }
    
        #endregion
    }
}